Notes (Week 9 Monday)
These are the notes I wrote during the lecture.
Very brief Hoare logic recap: Hoare triples {φ} P {ψ} φ precondition P program Ψ postcondition Reads: if φ is true in the initial state, then any state P can terminate in must satisfy ψ. { x contains the elements x_0,..,x_n } my_sorting_algorithm { x contains the elements x_0,..,x_n sorted in ascending order } Hoare logic: inference rules for proving Hoare triples ___________________ assign {φ[x:=e]} x:= e {φ} {φ} P {ρ} {ρ} Q {ψ} _______________________ seq {φ} P; Q {ψ} {φ ∧ b} P {ψ} {φ ∧ ¬b} Q {ψ} __________________________________ if {φ} if b then P else Q fi {ψ} {φ ∧ b} P {φ} __________________________________ while {φ} while b do P od {φ ∧ ¬b} φ ⇒ φ' {φ'} P {ψ'} Ψ' ⇒ Ψ ____________________________________ conseq {φ} P {ψ} ⊢ {⊤} P {⊥} ^ it implies every other Hoare triple (about P) by the rule of consequence ⊢ {⊥} P {⊤} ^ this is the strictly most useless Hoare triple: it says "if you never run P, ⊤ will hold" Two useful strats for finding loop invariants in this situation: i:=0 m:=1 while i < N do i := i + 1 m := m × i od 1: write a predicate that describes the current value of m If we can establish m = i! is a loop invariant Ask: does the postcondition follow? m = i! ∧ ¬i<N ⇒ m = N! ^ no :( let's try to add conjuncts to make it work m = i! ∧ i ≤ N ^ this will work m = i! ∧ i ≤ N ∧ ¬N < i ⇒ m = N! 2: write a predicate that describes how to obtain N! from the current values of m and i (skip) {1 ≤ N} {1 = fib(1) ∧ 1 = fib(1+1) ∧ 1 ≤ N} m := 1; {m = fib(1) ∧ 1 = fib(1+1) ∧ 1 ≤ N} n := 1; {m = fib(1) ∧ n = fib(1+1) ∧ 1 ≤ N} i := 1; {m = fib(i) ∧ n = fib(i+1) ∧ i ≤ N} while i < N do { m = fib(i) ∧ n = fib(i+1) ∧ i ≤ N ∧ i < N } * { n = fib(i+1) ∧ n+m = fib(i+1+1) ∧ i+1 ≤ N } t := m; { n = fib(i+1) ∧ n+t = fib(i+1+1) ∧ i+1 ≤ N } m := n; { m = fib(i+1) ∧ m+t = fib(i+1+1) ∧ i+1 ≤ N } n := m+t; { m = fib(i+1) ∧ n = fib(i+1+1) ∧ i+1 ≤ N } i := i+1 { m = fib(i) ∧ n = fib(i+1) ∧ i ≤ N } od { m = fib(i) ∧ n = fib(i+1) ∧ i ≤ N ∧ ¬(i<N) } { m = fib(N) } To prove the rule of consequence application at * we need to show that If m = fib(i) (1) and n = fib(i+1) (2) and i ≤ N (3) and i < N (4) Then we need to prove: n = fib(i+1) <-- exactly assumption (2) n+m = fib(i) + fib(i+1) = (by 1,2) = fib(i+2) = (by definition of fib) = fib(i+1+1) (cf. Russel & Whitehead) i+1 ≤ N (immediate from i < N) In assignment 1, there was an exercise where we modelled a connect 5 program as a relation between initial and final states. The agenda: define a way to *systematically* compute such pre-post-state relations for any program in 𝓛. ⟦P⟧ "the semantics of P", where P ∈ 𝓛 ⟦P⟧ ⊆ S × S where S is the set of all states A Hoare triple is provable if we can derive it using the inference rules of Hoare logic ⊢ {φ} P {Ψ} Given such a semantics, we can state what it means for a Hoare triple to be valid: ⊧ {φ} P {Ψ} iff ∀s,t ∈ S. (s,t) ∈ ⟦P⟧ ∧ ⟦φ⟧s ⇒ ⟦Ψ⟧t ∀s,t ∈ S. (s,t) ∈ ⟦P⟧ ∧ φ(s) ⇒ Ψ(t) Then we can state (and prove) e.g. *soundness* of Hoare logic: If ⊢ {φ} P {Ψ} then ⊧ {φ} P {Ψ} Or (TL;DR) we want to prove that Hoare logic "works", so we need to define what "works" means ^above < ⊆ ℕ × ℕ (just bog-standard less-than on nats) (<); (<) = {(n,m) | ∃x. n < x ∧ x < m} = {(n,m) | n + 1 < m} (<)({1,2,3}) = {2,3,4,5,6,...} (<)({}) = {} ⟦b; P⟧ b a predicate, P a program = ⟦b⟧; ⟦P⟧ = ⟦b⟧; ⟦P⟧ = {(η,η') | ∃η''. (η,η'') ∈ ⟦b⟧ ∧ (η'',η') ∈ ⟦P⟧} = {(η,η') | ∃η''. η=η'' ∧ ⟦b⟧η = true ∧ (η'',η') ∈ ⟦P⟧} = {(η,η') | ⟦b⟧η = true ∧ (η,η') ∈ ⟦P⟧} ⟦b⟧; ⟦P⟧ intuitively: the possible results of running P, but with b as an extra precondition R* is the least set defined by the following rules: (x,y) ∈ R (y,z) ∈ R* ___________ ____________________ (x,x) ∈ R* (x,z) ∈ R* We defined ⟦P⟧ using three equations and one inference rule (η,η') ∈ ⟦x := e⟧ if η' = η[x ↦ ⟦e⟧η] ⟦P; Q⟧ = ⟦P⟧; ⟦Q⟧ ⟦if b then P else Q fi⟧ = ⟦b; P⟧ ∪ ⟦¬b; Q⟧ ⟦while b do P od⟧ = ⟦b; P⟧*; ⟦¬b⟧